from __future__ import with_statement

from crv.model import DBSession, metadata
from crv.model.crvmodel import *
from crv.tools.clustermgr import ClusterMgr
from crv.tools.rolemgr import RoleMgr
from crv.tools.vmmgr import VMMgr
import sys, traceback
import logging
log = logging.getLogger(__name__)

def checkAll2():
    log.debug("checkAll2 Called")
    while True:
        checkAll()


checking=False
previousRunUpdate=-1

def checkAll():
    global checking

    if checking:
        log.info("checkAll checking already, return")
        return

    checking=True

    try:
        doCheckAll()
    except Exception, inst:
        log.error("*** ERRORERROR ***")
        exc_type, exc_value, exc_traceback = sys.exc_info()
        epr=traceback.format_exception(exc_type, exc_value,exc_traceback)
        for i in epr:
            log.error(i)

        checking=False

    finally:
        checking=False
        
def doCheckAll():
    global previousRunUpdate
    
    log.info("#"*256)
    log.info("checkAll Called")
    clMgr=ClusterMgr.getInstance()
    rlMgr=RoleMgr.getInstance()
    vmMgr=VMMgr.getInstance()    

    log.info("Checking VMs")
    vms = DBSession.query(VM).all()
    log.debug("checkAll::vms=%s"%str(vms))

    for ivm in vms:
        log.debug("checking VM:%s"%ivm.getAttr("name"))

        log.debug("getmaker=%s"%str(ivm.rp.getMaker("vm")))

        vmMgr.advanceStates(ivm)
        log.debug("Committing")

                
    log.debug("DIRTY=%s"%str(DBSession.dirty))
    transaction.commit()
    #raw_input("Press key to continue...")


    log.debug("*"*128)
    log.info("Checking Roles")

    roles = DBSession.query(Role).all()
    log.debug("checkAll::roles=%s"%str(roles))
    for irole in roles:
        log.debug("checking Role:%s"%irole.getAttr("name"))
        rlMgr.advanceStates(irole)
        log.debug("Committing")


    log.debug("DIRTY=%s"%str(DBSession.dirty))
    transaction.commit()
    #raw_input("Press key to continue...")

    log.debug("*"*128)

    log.info("Checking Clusters")

    clusters = DBSession.query(Cluster).all()
    log.debug("checkAll::clusters=%s"%str(clusters))
    for icluster in clusters:
        log.debug("checking Cluster:%s"%icluster.getAttr("name"))
        clMgr.advanceStates(icluster)
        log.debug("Committing")

        #Using newRunUpdate and previousRunUpdate to minimize database operations
        #control the interval of profile update
        #If targetSC is not currentSC (meaning it is still in transition) then set a small interval.
        if icluster.targetSC != icluster.currentSC:
            newRunUpdate=30
        else:
            newRunUpdate=60*30

        if newRunUpdate!=previousRunUpdate:
            previousRunUpdate=newRunUpdate
            for irole in icluster.role:
                irole.vm.setAttr("RunUpdate",str(newRunUpdate))
            
    log.debug("DIRTY=%s"%str(DBSession.dirty))
    transaction.commit()
    #raw_input("Press key to continue...")


def buildRoleDep(roles):
    for i in range(len(roles)):
        roles[i].dependOn=[]
#        roles[i].dependOnLocal=[]
        
        for j in range(i):

            if roles[j].roleDef in roles[i].roleDef.dependOn: #i depend on j
                log.debug("buildRoleDep:"+ roles[i].getAttr("name")+ " depends on "+ roles[j].getAttr("name"))
                roles[i].dependOn.append(roles[j])

        for ilc in roles[i].dependOnLocal:
            roles[i].dependOn.append(ilc)
                

